package io.vov.vitamio.tvpaser;


import io.vov.vitamio.entity.Online;
import io.vov.vitamio.entity.OnlineVideo;
import io.vov.vitamio.entity.OnlineVideoSource;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

 

/** 从XML读取电视台节目 */
public class XmlReaderHelper {

	/** 获取电视节目源更新文件 */
	public static Online getOnlineTVUpdateFile(InputStream input) {
		Online o = new Online();
		DocumentBuilderFactory docBuilderFactory = null;
		DocumentBuilder docBuilder = null;
		Document doc = null;
		try {
			docBuilderFactory = DocumentBuilderFactory.newInstance();
			docBuilder = docBuilderFactory.newDocumentBuilder();
			// xml file 放到 assets目录中的
			// doc = docBuilder.parse(context.getResources().getAssets()
			// .open("online.xml"));
			doc = docBuilder.parse(input);
			// root element
			Element root = doc.getDocumentElement();
			NodeList nodeList = root.getElementsByTagName("update");
			for (int i = 0; i < nodeList.getLength(); i++) {
				Node node = nodeList.item(i);
				NamedNodeMap attr = node.getAttributes();
				o.name = attr.getNamedItem("name").getNodeValue();
				o.version = attr.getNamedItem("version").getNodeValue();
				o.url = attr.getNamedItem("url").getNodeValue();
			}
		} catch (IOException e) {
		} catch (SAXException e) {
		} catch (ParserConfigurationException e) {
		} finally {
			try {
				input.close();
			} catch (Exception e2) {
				// TODO: handle exception
			}
			input = null;
			doc = null;
			docBuilder = null;
			docBuilderFactory = null;
		}
		return o;
	}
	
	/** 获取所有电视分类 */
	public static ArrayList<OnlineVideo> getAllCategory(InputStream input) {
		ArrayList<OnlineVideo> result = new ArrayList<OnlineVideo>();
		DocumentBuilderFactory docBuilderFactory = null;
		DocumentBuilder docBuilder = null;
		Document doc = null;
		try {
			docBuilderFactory = DocumentBuilderFactory.newInstance();
			docBuilder = docBuilderFactory.newDocumentBuilder();
			// xml file 放到 assets目录中的
			// doc = docBuilder.parse(context.getResources().getAssets()
			// .open("online.xml"));
			doc = docBuilder.parse(input);
			// root element
			Element root = doc.getDocumentElement();
			NodeList nodeList = root.getElementsByTagName("category");
			for (int i = 0; i < nodeList.getLength(); i++) {
				Node node = nodeList.item(i);// category
				OnlineVideo ov = new OnlineVideo();
				NamedNodeMap attr = node.getAttributes();
				ov.title = attr.getNamedItem("name").getNodeValue();
				ov.categoryId = attr.getNamedItem("id").getNodeValue();
				ov.category = 1;
				ov.level = 2;
				ov.is_category = true;
				result.add(ov);
				// Read Node
			}
		} catch (IOException e) {
		} catch (SAXException e) {
		} catch (ParserConfigurationException e) {
		} finally {
			try {
				input.close();
			} catch (Exception e2) {
				// TODO: handle exception
			}
			input = null;
			doc = null;
			docBuilder = null;
			docBuilderFactory = null;
		}
		return result;
	}

	/** 读取分类下所有电视地址 */
	public static ArrayList<OnlineVideo> getVideos(InputStream input, String categoryId) {
		ArrayList<OnlineVideo> result = new ArrayList<OnlineVideo>();
		DocumentBuilderFactory docBuilderFactory = null;
		DocumentBuilder docBuilder = null;
		Document doc = null;
		try {
			docBuilderFactory = DocumentBuilderFactory.newInstance();
			docBuilderFactory.setNamespaceAware(true);
			docBuilder = docBuilderFactory.newDocumentBuilder();
			// xml file 放到 assets目录中的
//			doc = docBuilder.parse(context.getResources().getAssets().open("online.xml"));
			doc = docBuilder.parse(input);
			// root element
			NodeList nodeList = null;
			Element root = doc.getElementById(categoryId);
			if (root == null) {
				// getElementById j2se环境下失效
				NodeList childList = doc.getElementsByTagName("category");
				final int length = childList.getLength();
				for (int i = 0; i < length; i++) {
					if (((Element) childList.item(i)).getAttribute("id").equals(categoryId)) {
						root = (Element) childList.item(i);
						break;
					}
				}
			}
			if (root != null) {
				nodeList = root.getChildNodes();
				for (int i = 0, j = nodeList.getLength(); i < j; i++) {
					Node baseNode = nodeList.item(i);
					if (!"item".equals(baseNode.getNodeName()))
						continue;
					String id = baseNode.getFirstChild().getNodeValue();
					if (id == null) {
						continue;
					}
					Element el = doc.getElementById(id);
					OnlineVideo ov = parserOnlineVideo(el);
					if (ov != null && ov.getSourceList() != null && ov.getSourceList().size() > 0) {
						result.add(ov);
					}
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} finally {
			try {
				input.close();
			} catch (Exception e2) {
				// TODO: handle exception
			}
			doc = null;
			docBuilder = null;
			docBuilderFactory = null;
		}
		return result;
	}
	
	/**
	 * 读取所有电视台数据
	 * @param input
	 * @param categoryId
	 * @return
	 */
	public static ArrayList<OnlineVideo> getAllVideos(InputStream input) {
		ArrayList<OnlineVideo> result = new ArrayList<OnlineVideo>();
		DocumentBuilderFactory docBuilderFactory = null;
		DocumentBuilder docBuilder = null;
		Document doc = null;
		try {
			docBuilderFactory = DocumentBuilderFactory.newInstance();
			docBuilderFactory.setNamespaceAware(true);
			docBuilder = docBuilderFactory.newDocumentBuilder();
			// xml file 放到 assets目录中的
//			doc = docBuilder.parse(context.getResources().getAssets().open("online.xml"));
			doc = docBuilder.parse(input);
			// root element
			Element root = doc.getDocumentElement();
			if (root != null) {
				NodeList nodeList = root.getElementsByTagName("media");
				for (int i = 0, j = nodeList.getLength(); i < j; i++) {
					OnlineVideo ov = parserOnlineVideo((Element) nodeList.item(i));
					if (ov != null && ov.getSourceList() != null && ov.getSourceList().size() > 0) {
						result.add(ov);
					}
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} finally {
			try {
				input.close();
			} catch (Exception e2) {
				// TODO: handle exception
			}
			doc = null;
			docBuilder = null;
			docBuilderFactory = null;
		}
		return result;
	}
	
	
	/**
	 * 读取所有电视台数据
	 * @param input
	 * @param categoryId
	 * @return
	 * @throws Exception 
	 *//*
	public static ArrayList<OnlineVideo> getAllVideos2(InputStream input) throws Exception {
		
		Logger logger = Logger.getLogger(XmlReaderHelper.class);

		ArrayList<OnlineVideo> onlineList = new ArrayList<OnlineVideo>();
		DocumentBuilderFactory docBuilderFactory = null;
		DocumentBuilder docBuilder = null;
		Document doc = null;
		try {
			//step1: 解析电视台列表
			docBuilderFactory = DocumentBuilderFactory.newInstance();
			docBuilderFactory.setNamespaceAware(true);
			docBuilder = docBuilderFactory.newDocumentBuilder();
			// xml file 放到 assets目录中的
//			doc = docBuilder.parse(context.getResources().getAssets().open("online.xml"));
			doc = docBuilder.parse(input);
			// root element
			Element root = doc.getDocumentElement();
			if (root != null) {
				NodeList nodeList = root.getElementsByTagName("media");
				for (int i = 0, j = nodeList.getLength(); i < j; i++) {
					OnlineVideo ov = parserOnlineVideo((Element) nodeList.item(i));
					if (ov != null && ov.getSourceList() != null && ov.getSourceList().size() > 0) {
						ov.el = (Element) nodeList.item(i);
						onlineList.add(ov);
					}
				}
			}
			
			// step2: 从网络读取节目单
			final int size = onlineList.size();
			logger.warn("总共电视台数量: " + size);
			for (int i = 0; i < 100; i++) {
				List<TVProgram> tvprogramList = OnlineTVParser.getTVprogramDateSet(i + 1 + "", "", "");
				if (tvprogramList != null && tvprogramList.size() > 0) {
					TVProgram tvProgram = tvprogramList.get(0);
					String tvinfo = tvProgram.getTvStationInfo();
					logger.warn("找到节目表：" + (i + 1) + " 电视台: "+ tvinfo);
					String[] tvalias = tvinfo.split("\\|| ");
					if (tvalias == null) {
						tvalias = new String[] { tvinfo };
					}
					boolean match_flag = false;
					OnlineVideo onlineVideo;
					//step3:找到匹配的电视台
					for (int j = 0; j < size; j++) {
						onlineVideo = onlineList.get(j);
						if(!StringUtil.isNull(onlineVideo.getSource_code())){
							continue;
						}
						for (int k = 0; k < tvalias.length; k++) {
							if (!StringUtil.isNull(tvalias[k])
									&& (tvalias[k].indexOf(onlineVideo.getTitle().trim()) >= 0 || onlineVideo.getTitle().indexOf(tvalias[k].trim()) == 0)) {
								logger.warn("匹配到目标电视台: " + onlineVideo.getTitle() + " id: " + onlineVideo.getId());
								onlineVideo.setSource_code(i + 1+"");
								onlineVideo.el.setAttribute("source_code", i + 1 + "");
								match_flag = true;
								break;
							}
						}
//						if (match_flag) {
//							break;
//						}
					}
				}
				
				Thread.sleep(1000);
			}
			
			//step4:保存xml
			TransformerFactory tf = TransformerFactory.newInstance();
			Transformer transformer = tf.newTransformer();
			DOMSource source = new DOMSource(doc);
			transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
			transformer.setOutputProperty(OutputKeys.INDENT, "yes");
			PrintWriter pw = new PrintWriter(new FileOutputStream("F:\\CVSROOT\\Android\\机顶盒项目\\online_" + System.currentTimeMillis() + ".xml"));
			StreamResult result = new StreamResult(pw);
			transformer.transform(source, result);
			
		} catch (IOException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} finally {
			try {
				input.close();
			} catch (Exception e2) {
				// TODO: handle exception
			}
			doc = null;
			docBuilder = null;
			docBuilderFactory = null;
		}
		return onlineList;
	}
	
	*//**
	 * 读取所有电视台数据
	 * @param input
	 * @param categoryId
	 * @return
	 * @throws Exception 
	 * @Deprecated
	 *//*
	public static ArrayList<OnlineVideo> getAllVideos3(InputStream input) throws Exception {
		
		int match_count = 0;
		int local_size =0;
		int channel_size =0;
		Logger logger = Logger.getLogger(XmlReaderHelper.class);

		ArrayList<OnlineVideo> onlineList = new ArrayList<OnlineVideo>();
		DocumentBuilderFactory docBuilderFactory = null;
		DocumentBuilder docBuilder = null;
		Document doc = null;
		try {
			//step1: 解析电视台列表
			docBuilderFactory = DocumentBuilderFactory.newInstance();
			docBuilderFactory.setNamespaceAware(true);
			docBuilder = docBuilderFactory.newDocumentBuilder();
			// xml file 放到 assets目录中的
//			doc = docBuilder.parse(context.getResources().getAssets().open("online.xml"));
			doc = docBuilder.parse(input);
			// root element
			Element root = doc.getDocumentElement();
			if (root != null) {
				NodeList nodeList = root.getElementsByTagName("media");
				for (int i = 0, j = nodeList.getLength(); i < j; i++) {
					OnlineVideo ov = parserOnlineVideo((Element) nodeList.item(i));
					if (ov != null && ov.getSourceList() != null && ov.getSourceList().size() > 0) {
						ov.el = (Element) nodeList.item(i);
						onlineList.add(ov);
					}
				}
			}
			
			// step2: 从网络读取节目单
			
			List<String> tvChannelList = FileUtils.readLines(new File("D:\\eclipse\\workspace7\\JAVADemo\\tv.log"));
			local_size = onlineList.size();
			channel_size = tvChannelList.size();
			for (int j = 0; j < channel_size; j++) {
				if (tvChannelList != null && tvChannelList.size() > 0) {
					String tvinfo = tvChannelList.get(j);
					if(tvinfo.indexOf("|") <= 0){
						continue;
					}
//					tvinfo = tvinfo.substring(tvinfo.indexOf("@@")+2);
					String tvalias = tvinfo.split("\\|")[0].trim();
//					String tv_code = tvinfo.substring(tvinfo.lastIndexOf("/")+1);
//					tv_code = tv_code.substring(0, tv_code.lastIndexOf("-"));
					String tv_code = tvinfo.split("\\|")[1].trim();
					System.err.println("读取到本地电视台: " + tvalias + "	code: " + tv_code );
					OnlineVideo onlineVideo;
					//step3:找到匹配的电视台
					for (int k = 0; k < local_size; k++) {
						onlineVideo = onlineList.get(k);
						if (!StringUtil.isNull(onlineVideo.getSource_code())) {
							continue;
						}
						if (!StringUtil.isNull(tvalias)){
							boolean match = false;
							if(tvalias.indexOf(onlineVideo.getTitle().trim()) >= 0 || onlineVideo.getTitle().indexOf(tvalias.trim()) == 0) {
								//单纯字符匹配
								match = true;
							}
							String shortalias = tvalias.replace("频道", "");
							if(shortalias.indexOf(onlineVideo.getTitle().trim()) >= 0 || onlineVideo.getTitle().indexOf(shortalias.trim()) == 0) {
								//去掉频道匹配
								match = true;
							}
							String onlinealias= onlineVideo.getTitle().replace("频道", "");
							if(shortalias.indexOf(onlinealias.trim()) >= 0 || onlinealias.indexOf(shortalias.trim()) == 0) {
								//去掉频道匹配
								match = true;
							}
							if (shortalias.indexOf(" ") > 0 && onlinealias.indexOf(shortalias.replaceAll(" ", "").trim()) >= 0) {
								match = true;
							}
							if (onlinealias.indexOf(" ") > 0 && shortalias.indexOf(onlinealias.replaceAll(" ", "").trim()) >= 0) {
								match = true;
							}
							
							onlineVideo.el.setAttribute("source_code", "");
							if(match){
								onlineVideo.setSource_code(tv_code);
								onlineVideo.el.setAttribute("source_code", tv_code);
								logger.warn("匹配到目标电视台: " + onlineVideo.getTitle() + " id: " + onlineVideo.getId());
								match_count ++;
							}
						}
					}
				}
				
//				Thread.sleep(1000);
			}
			
			//step4:保存xml
			TransformerFactory tf = TransformerFactory.newInstance();
			Transformer transformer = tf.newTransformer();
			DOMSource source = new DOMSource(doc);
			transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
			transformer.setOutputProperty(OutputKeys.INDENT, "yes");
			PrintWriter pw = new PrintWriter(new FileOutputStream("F:\\CVSROOT\\Android\\机顶盒项目\\online_" + System.currentTimeMillis() + ".xml"));
			StreamResult result = new StreamResult(pw);
			transformer.transform(source, result);
			
			System.err.println("*********************************");
			for (int k = 0; k < local_size; k++) {
				OnlineVideo onlineVideo = onlineList.get(k);
				if (StringUtil.isNull(onlineVideo.getSource_code())) {
					System.err.println("没有匹配的电视台: " + onlineVideo.getTitle() );
				}
			}
			System.err.println("*********************************");
		} catch (IOException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} finally {
			try {
				input.close();
			} catch (Exception e2) {
				// TODO: handle exception
			}
			doc = null;
			docBuilder = null;
			docBuilderFactory = null;
			System.err.println("*********************************");
			System.err.println("匹配结束,本地电视台数量: " + local_size + " 网络抓取数量: " + channel_size+ "	总共匹配到: " + match_count + " 个电视台.");
			System.err.println("*********************************");
		}
		return onlineList;
	}
	*/
	
	/**
	 * 解析电视台节点并返回电视台数据
	 * @param el
	 * @return
	 */
	private static OnlineVideo parserOnlineVideo(Element el){
		OnlineVideo ov = null;
		if (el != null) {
			ov = new OnlineVideo();
			ov.num = el.getAttribute("id");
			ov.title = el.getAttribute("title");
			ov.icon_url = el.getAttribute("image");
			ov.version = el.getAttribute("version");
			ov.title = el.getAttribute("title");
			ov.source_code = el.getAttribute("source_code");
			ov.icon_url = el.getAttribute("image");
			ov.guide = el.getAttribute("guide");
			ov.desc = el.getAttribute("desc");
			ov.level = 3;
			ov.category = 1;
			NodeList nodes = el.getChildNodes();
			for (int m = 0, n = nodes.getLength(); m < n; m++) {
				Node node = nodes.item(m);
				if (!"ref".equals(node.getNodeName()))
					continue;
				OnlineVideoSource onlineVideoSource = new OnlineVideoSource();
				onlineVideoSource.setLink(node.getAttributes().getNamedItem("href").getNodeValue());
				onlineVideoSource.setWidth(Integer.parseInt(node.getAttributes().getNamedItem("width").getNodeValue()));
				onlineVideoSource.setHeight(Integer.parseInt(node.getAttributes().getNamedItem("height").getNodeValue()));
				onlineVideoSource.setBitrate(Integer.parseInt(node.getAttributes().getNamedItem("bitrate").getNodeValue()));
				ov.addSource(onlineVideoSource);
			}
		}
		
		return ov;
	}
	
	
}
